// (C) Copyright 2012 Kystar. All rights reserved.

`timescale 1ns/100ps
`default_nettype none

module crc_check
(
    input  wire          I_sclk,
    input  wire          I_rst_n,
    //
    input  wire          I_net_en,
    input  wire  [ 7: 0] I_net_data,
    //output
    output reg           O_error,
    output reg           O_crc_check_complete
);

/******************************************************************************
                                <localparams>
******************************************************************************/

localparam  HEAD_BYTES = 8;

/******************************************************************************
                              <internal signals>
******************************************************************************/

reg  crc_en;
reg  data_en;
reg  invert_en;
reg  [ 7: 0] din;
wire [ 31: 0] crc32_value;
reg  [ 11: 0] bytes_cnt;
reg  [ 3: 0] net_en_dly;

/******************************************************************************
                              <module body>
******************************************************************************/

// Instantiate the module
crc32_d8_01 utt_crc32_d8_01 (
    .sclk(I_sclk), 
    .crc_en(crc_en), 
    .data_en(data_en), 
    .invert_en(invert_en), 
    .din(din), 
    .crc32_value(crc32_value), 
    .tout()
    );

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        bytes_cnt <= 'd0;
    else if(!I_net_en)
        bytes_cnt <= 'd0;
    else
        bytes_cnt <= bytes_cnt + 1'b1;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        net_en_dly <= 'd0;
    else
        net_en_dly <= {net_en_dly[2:0],I_net_en};

always @(posedge I_sclk)
    if (I_net_en)
        din <= I_net_data;
    else
        din <= 'd0;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        crc_en <= 1'b0;
    else 
        crc_en <= I_net_en;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        data_en <= 1'b0;
    else if(bytes_cnt == HEAD_BYTES)
        data_en <= 1'b1;
    else if(!I_net_en)
        data_en <= 1'b0;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        invert_en <= 1'b0;
    else
        invert_en <= (bytes_cnt >= 8) && (bytes_cnt < 8 + 4);

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        O_error <= 1'b0;
    else if(I_net_en)
        O_error <= 1'b0;
    else if(net_en_dly[1] && !net_en_dly[0] && crc32_value != 32'hffffffff) 
        O_error <= 1'b1;

always @(posedge I_sclk or negedge I_rst_n)
    if (!I_rst_n)
        O_crc_check_complete <= 1'b0;
    else if(net_en_dly[1] && !net_en_dly[0])
        O_crc_check_complete <= 1'b1;
    else
        O_crc_check_complete <= 1'b0;



endmodule
`default_nettype wire

